/**
 * kl yy-ds @2021
 */
package com.cxps.server.auth;

import com.cxps.cloud.code.ImageVerificationCode;
import com.cxps.cloud.common.ConstantPool;
import com.cxps.cloud.message.ApiResponse;
import com.cxps.cloud.utils.RegularUtils;
import com.cxps.server.vip.domain.VIPInfo;
import com.cxps.server.vip.service.VIPService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 登录认证控制层
 * https://blog.csdn.net/q438944209/article/details/82920461
 * https://blog.csdn.net/BecauseSy/article/details/90411441
 * https://www.jianshu.com/p/e35454a18e13
 *
 * @author YouCai.Liu
 * @since 2021/10/24
 * ...
 */
@Slf4j
@RestController
@Api(tags = "认证授权API")
@RequestMapping("/admin/auth")
public class AuthController {

    @Autowired
    private AuthService authService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private VIPService vipService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * ERP项目登录接口
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @GetMapping("/login")
    public ApiResponse login(@RequestParam String username, @RequestParam String password) {
        try {
            Assert.hasLength(username, "用户名不能为空");
            Assert.hasLength(password, "密码不能为空");
            return ApiResponse.fireSuccess(authService.login(username, password));
        } catch (IllegalArgumentException e) {
            log.error("登录失败：" + e.getMessage(), e);
            return ApiResponse.fireError(e.getMessage());
        }
    }

    /**
     * 新零售登录接口
     *
     * @param username
     * @param password
     * @return
     */
    @GetMapping("/login.do")
    public ApiResponse login2(@RequestParam String username, @RequestParam String password) {
        try {
            Assert.hasLength(username, "用户名不能为空");
            Assert.hasLength(password, "密码不能为空");
            return ApiResponse.fireSuccess(authService.login2(username, password));
        } catch (IllegalArgumentException e) {
            log.error("登录失败：" + e.getMessage(), e);
            return ApiResponse.fireError(e.getMessage());
        }
    }

    /**
     * 获取图片验证码参数
     *
     * @return
     */
    @GetMapping("/imgCode")
    public void getImgCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 创建生成验证码类对象
        ImageVerificationCode ivc = new ImageVerificationCode();

        // 获取验证码
        BufferedImage image = ivc.getImage();

        // 将验证码文本存在redis
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(ConstantPool.R_IMG_CODE + ivc.getText().toLowerCase(), ivc.getText(), 5 * 60 * 1000);

        // 将验证码图片响应给客户端
        ivc.output(image, response.getOutputStream());
    }

    /**
     * 获取手机验证码
     *
     * @param imgCode  图形验证码
     * @param phoneNum 手机号
     * @throws IOException
     */
    @GetMapping("/phoneCode")
    public ApiResponse getPhoneCode(@RequestParam String imgCode, @RequestParam String phoneNum) {
        try {
            Assert.hasLength(imgCode, "图形验证码不能为空");
            Assert.hasLength(phoneNum, "手机号不能为空");

            // 验证手机号
            boolean mobile = RegularUtils.isMobile(phoneNum);
            if (!mobile) {
                throw new IllegalArgumentException("手机号码格式错误");
            }

            // 验证图形验证码
            ValueOperations valueOperations = redisTemplate.opsForValue();
            Object redisImgCode = valueOperations.get(ConstantPool.R_IMG_CODE + imgCode.toLowerCase());
            if (null == redisImgCode) {
                throw new IllegalArgumentException("图形验证码错误");
            }

            // 验证手机号是否被注册
            vipService.singleVIP(phoneNum);

            // 生成随机验证码
            String phoneCode = "111111";
//            String phoneCode = PhoneCode.buildCode();
            // 发送短信

            // 将短信验证码存到redis
            valueOperations.set(ConstantPool.R_PHONE_CODE + phoneNum, phoneCode);

            return ApiResponse.fireSuccess();
        } catch (IllegalArgumentException e) {
            log.error("获取手机验证码失败：" + e.getMessage(), e);
            return ApiResponse.fireError(e.getMessage());
        }
    }

    /**
     * 验证手机验证码
     *
     * @param phoneCode
     * @param phoneNum
     * @return
     */
    @GetMapping("/checkPhoneCode")
    public ApiResponse checkPhoneCode(@RequestParam String phoneCode, @RequestParam String phoneNum) {
        try {
            Assert.hasLength(phoneCode, "手机验证码不能为空");
            Assert.hasLength(phoneNum, "手机号不能为空");

            // 验证手机验证码
            ValueOperations valueOperations = redisTemplate.opsForValue();
            Object redisImgCode = valueOperations.get(ConstantPool.R_PHONE_CODE + phoneNum);
            if (null == redisImgCode) {
                throw new IllegalArgumentException("手机验证码错误");
            }
            if(!redisImgCode.toString().equals(phoneCode)){
                throw new IllegalArgumentException("手机验证码错误");
            }

            // 将数据保存
            VIPInfo info = new VIPInfo();
            info.setVipPhone(phoneNum);
            // 生成随机密码，通过短信告知
            // 设置密码必须加密
            info.setPassword(passwordEncoder.encode("123456"));
            vipService.add(info);

            return ApiResponse.fireSuccess();
        } catch (IllegalArgumentException e) {
            log.error("验证手机验证码失败：" + e.getMessage(), e);
            return ApiResponse.fireError(e.getMessage());
        }

    }

}
